module EnorDecode(clk,keyadsel,mixsel,reginsel,wrregen,en_de,intxt,roundkey,outtxt);

    output [127:0] outtxt;
    input clk,wrregen,mixsel,reginsel,en_de;//ende 0 加密 1 解密
    input [1:0] keyadsel;
    input [127:0] intxt,roundkey;

    wire [7:0] sbout[0:15];
    wire [7:0] sbout0[0:15];
    wire [7:0] sbout1[0:15];

    wire [7:0] a [0:15]; wire [7:0] b [0:15];
    wire [7:0] c [0:15]; wire [7:0] d [0:15];
    wire [7:0] e [0:15]; wire [7:0] f [0:15];
    wire [7:0] g [0:15]; wire [7:0] i [0:15];
    wire [7:0] j [0:15]; wire [7:0] m [0:15];

    wire [7:0]f02[0:15]; wire [7:0]f03[0:15];
    wire [7:0]f09[0:15]; wire [7:0]f0b[0:15];
    wire [7:0]f0d[0:15]; wire [7:0]f0e[0:15];

    wire [127:0] d1,e1,g1,h1;
    genvar k;
    generate
        for(k=0;k<16;k=k+1)begin : CUL
            sbox_fpga  sboxx(outtxt[(16-k)*8-1:(15-k)*8],sbout0[k]);
            sbox_fpga_ sbox_(outtxt[(16-k)*8-1:(15-k)*8],sbout1[k]);

            mux21_8 mux218_(en_de,sbout0[k],sbout1[k],sbout[k]);
            mux21_8 mux218(mixsel,sbout[k],m[k],f[k]);

            byte0203 b0203(f[k],f02[k],f03[k]);
            byte9bde b9bde(f[k],f02[k],f03[k],f09[k],f0b[k],f0d[k],f0e[k]);

            assign c[k] = a[k] ^ b[k];
            assign g[k] = i[k] ^ j[k];

            assign e1[(16-k)*8-1:(15-k)*8] = e[k];
            assign g1[(16-k)*8-1:(15-k)*8] = g[k];
            assign d1[(16-k)*8-1:(15-k)*8] = d[k];
            
            assign e[k] = d[k] ^ roundkey[(16-k)*8-1:(15-k)*8];
        end
    endgenerate

    genvar k4;
    generate
        for(k4=0;k4<4;k4=k4+1)begin : mix_array

            assign m[k4*4  ]=sbout[(k4*4+0) %16]^roundkey[(16-(k4*4  ))*8-1:(15-(k4*4  ))*8];
            assign m[k4*4+1]=sbout[(k4*4+13)%16]^roundkey[(16-(k4*4+1))*8-1:(15-(k4*4+1))*8];
            assign m[k4*4+2]=sbout[(k4*4+10)%16]^roundkey[(16-(k4*4+2))*8-1:(15-(k4*4+2))*8];
            assign m[k4*4+3]=sbout[(k4*4+7) %16]^roundkey[(16-(k4*4+3))*8-1:(15-(k4*4+3))*8];

            assign i[k4*4  ] = f0e[k4 * 4 + 0] ^ f0b[k4 * 4 + 1];
            assign i[k4*4+1] = f09[k4 * 4 + 0] ^ f0e[k4 * 4 + 1];
            assign i[k4*4+2] = f0d[k4 * 4 + 0] ^ f09[k4 * 4 + 1];
            assign i[k4*4+3] = f0b[k4 * 4 + 0] ^ f0d[k4 * 4 + 1];

            assign j[k4*4  ] = f0d[k4 * 4 + 2] ^ f09[k4 * 4 + 3];
            assign j[k4*4+1] = f0b[k4 * 4 + 2] ^ f0d[k4 * 4 + 3];
            assign j[k4*4+2] = f0e[k4 * 4 + 2] ^ f0b[k4 * 4 + 3];
            assign j[k4*4+3] = f09[k4 * 4 + 2] ^ f0e[k4 * 4 + 3];

            assign a[k4*4  ] =   f02[k4 * 4] ^   f03[(k4 * 4 + 5) % 16];
            assign a[k4*4+1] = sbout[k4 * 4] ^   f02[(k4 * 4 + 5) % 16];
            assign a[k4*4+2] = sbout[k4 * 4] ^ sbout[(k4 * 4 + 5) % 16];
            assign a[k4*4+3] =   f03[k4 * 4] ^ sbout[(k4 * 4 + 5) % 16];

            assign b[k4*4  ] = sbout[(k4 * 4 + 10) % 16]  ^ sbout[(((k4 * 4 + 10) % 16) + 5) % 16];
            assign b[k4*4+1] =   f03[(k4 * 4 + 10) % 16]  ^ sbout[(((k4 * 4 + 10) % 16) + 5) % 16];
            assign b[k4*4+2] =   f02[(k4 * 4 + 10) % 16]  ^   f03[(((k4 * 4 + 10) % 16) + 5) % 16];
            assign b[k4*4+3] = sbout[(k4 * 4 + 10) % 16]  ^   f02[(((k4 * 4 + 10) % 16) + 5) % 16];

            // MUX418  sbout
            // | 0     0   | 4     4   | 8     8     | 12    12 |
            // | 5     13  | 9     1   | 13    5     | 1     9  |
            // | 10    10  | 14    14  | 2     2     | 6     6  |
            // | 15    7   | 3     11  | 7     15    | 11    3  |
            mux41_8  mux4180(keyadsel,intxt[(16-(k4*4+0))*8-1:(15-(k4*4+0))*8],c[k4*4+0],
                                            sbout[(k4*4   )%16],sbout[(k4*4    )%16],d[k4*4+0]);
            mux41_8  mux4181(keyadsel,intxt[(16-(k4*4+1))*8-1:(15-(k4*4+1))*8],c[k4*4+1],
                                            sbout[(k4*4+5 )%16],sbout[(k4*4+13 )%16],d[k4*4+1]);
            mux41_8  mux4182(keyadsel,intxt[(16-(k4*4+2))*8-1:(15-(k4*4+2))*8],c[k4*4+2],
                                            sbout[(k4*4+10)%16],sbout[(k4*4+10 )%16],d[k4*4+2]);
            mux41_8  mux4183(keyadsel,intxt[(16-(k4*4+3))*8-1:(15-(k4*4+3))*8],c[k4*4+3],
                                            sbout[(k4*4+15)%16],sbout[(k4*4+7  )%16],d[k4*4+3]);
        end
    endgenerate

    mux21_128  mux21_128_0(reginsel,e1,g1,h1);

    reg_128 resultreg(clk,wrregen,h1,outtxt);   

endmodule